home *** CD-ROM | disk | FTP | other *** search
- // 3rd person camera with line of sight at the top of the player's head which means the
- // player's head stays at the center of the view. Also gives a stable view when the camera
- // wants to go into an obstruction and has camera-to-player zoom.
- var camera_max_dist = 160; // distance limit for camera range adjustment
- var temp2[3];
- var camera_dist[3] = 90,0,0; // new default value for desired camera distance to player
- function zoom_view_3rd() // press (+=) key to zoom out, shift(+=) to zoom in (only in 3rd person)
- { if (KEY_SHIFT)
- { camera_dist.X -= .1*camera_max_dist;
- if (camera_dist.X < .1*camera_max_dist) { camera_dist.X = .1*camera_max_dist;}
- } else
- { camera_dist.X += .1*camera_max_dist;
- if (camera_dist.X > camera_max_dist) { camera_dist.X = camera_max_dist;}
- }
- }
- ON_EQUALS zoom_view_3rd; // hope the += key doesn't conflict with anything
- function move_view_3rd() // the old function flickers when the camera wants to go into the wall
- {
- if ((_camera == 0) && (player != NULL))
- {
- CAMERA.DIAMETER = 0; // make the camera passable
- CAMERA.genius = player;
- CAMERA.pan += 0.2 * ang(player.pan-CAMERA.pan);
- // tilt the camera differently if we are using a vehicle
- if ( (player._MOVEMODE == _MODE_PLANE)| |(player._MOVEMODE == _MODE_CHOPPER))
- {
- CAMERA.tilt += 0.2 * ang(player.tilt-CAMERA.tilt);
- }
- else // walking, swimming etc.
- {
- CAMERA.tilt += 0.2 * ang(head_angle.tilt-CAMERA.tilt);
- }
-
- // Merlinson start of my hack for the camera blocked by obstacles, adds 1 trace per frame normally
- vec_set(temp, temp_cdist); // length of temp is set to temp_cdist.X
- temp2.PAN = player.PAN; // want to do both pan and tilt in one rotate
- temp2.TILT = head_angle.tilt; // player's pan and head_angle's tilt
- temp2.ROLL = 0;
- vec_rotate(temp, temp2); // temp now has player's pan and head_angle's tilt
- vec_set(temp2, player.X); // temp2 will become the desired camera position
- vec_sub(temp2, temp); // temp2 is temp_cdist.X behind the player view
- trace_mode = ignore_me + ignore_passable; // set up trace mode options
- result = trace(player.X, temp2); // check for line of sight from player to temp2
- if (result > 0) // temp2 is blocked by something, maybe a wall
- { vec_scale(temp, .8); // reducing temp will move temp2 closer to player
- temp_cdist.X *= .8; // reduce temp_cdist.X by 20% for next pass
- }
- else // temp2 location can see the player
- { if (temp_cdist.X < camera_dist.X) // we can try to back away from the player
- { vec_set(temp2, player.X); // we're going to recalculate temp2
- vec_scale(temp, 1.05); // increase distance 5%
- vec_sub(temp2, temp); // temp2 is 5% farther away
- trace_mode = ignore_me + ignore_passable; // trace mode options
- result = trace(player.X, temp2); // check for line of sight again
- if (result > 0) // something is blocking, can't back up
- { vec_scale(temp, 1.0/1.05); // restore temp and don't change temp_cdist.X
- }
- else // the camera can move further back
- { temp_cdist.X *= 1.05; // increase temp_cdist.X by 5% for next pass
- }
- }
- if (temp_cdist.X > camera_dist.X) // temp_cdist.X is too big or we zoomed in
- { temp_cdist.X = camera_dist.X; // limit the max value of temp_cdist.X
- }
- }
- // the camera responds slowly and smooths the jerkiness of temp2's location changes
- CAMERA.X += 0.4*(player.X - temp.X - CAMERA.X);
- CAMERA.Y += 0.4*(player.Y - temp.Y - CAMERA.Y);
- // got the camera height from trying to match the 1st person function's eye height
- // but it came out about shoulder height, so I fudged it higher a bit
- // now the camera is right at the top of his head (on the guard model)
- temp.X = player.Z + player.MIN_Z + 2.1*eye_height_up*(player.MAX_Z - player.MIN_Z);
- CAMERA.Z += 0.3*(temp.X - temp.Z - CAMERA.Z);
- // check to see if camera is located in a passable block
- result = ent_content(NULL,CAMERA.X);
-
- // Merlinson end of my hack
- if (result == CONTENT_PASSABLE)
- {
- if (FOG_COLOR != _FOG_UNDERWATER)
- {
- current_fog_index = FOG_COLOR; // save old fog
- FOG_COLOR = _FOG_UNDERWATER; // set fog color to underwater fog
- }
- }
- else
- {
- if (FOG_COLOR == _FOG_UNDERWATER)
- {
- // else restore current_fog_index
- FOG_COLOR = 1;
- }
- }
- person_3rd = 1;
- }
- }